/*
 * 文件名：HttpClientUtil.java
 * 版权：Copyright by www.youkeshu.com
 * 描述：
 * 创建人：liuxiaoliang
 * 创建时间：2018年7月3日
 * 修改理由：
 * 修改内容：
 */
package com.yks.hbo.amazon.util;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPatch;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.util.CollectionUtils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * http请求工具类
 *
 * @author liuxiaoliang
 * @version 1.0
 * @date 2018年7月3日
 * @since JDK1.8
 */
public class HttpClientUtil {
    private static Logger LOGGER = LogManager.getLogger(HttpClientUtil.class);

    private static Charset CHARSET = Charset.forName("UTF-8");

    private static int CONNECTION_REQUEST_TIMEOUT = 30000;
    private static int SOCKET_TIMEOUT = 60000;
    private static int CONNECT_TIMEOUT = 60000;

    /**
     * 发送多参数的get请求
     *
     * @param url   请求路径
     * @param param 参数Map
     * @return
     */

    public static String doGet(String url, Map<String, String> param) {

        // 创建Httpclient对象
        CloseableHttpClient httpclient = HttpClients.createDefault();

        String resultString = "";
        CloseableHttpResponse response = null;
        try {
            // 创建uri
            URIBuilder builder = new URIBuilder(url);
            if (param != null) {
                for (String key : param.keySet()) {
                    builder.addParameter(key, param.get(key));
                }
            }
            URI uri = builder.build();
            // 创建http GET请求
            HttpGet httpGet = new HttpGet(uri);

            httpGet = setHttpGetConfig(httpGet);
            // 执行请求
            response = httpclient.execute(httpGet);
            // 判断返回状态是否为200
            if (response.getStatusLine().getStatusCode() == 200) {
                resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
            }
        } catch (Exception e) {
            LOGGER.error("doGet url{},{}",url,e.getMessage());
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpclient.close();
            } catch (IOException e) {
                LOGGER.error("HttpClientUtil doGet error", e.getMessage());
            }
        }
        return resultString;
    }

    /**
     * 有请求头的GET请求
     * @date 2020/10/14 15:12
     */
    public static String doGetByHeaders(String url, Map<String, String> headers) throws Exception {
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        String result = "";
        try {
            httpClient = HttpClients.createDefault();
            HttpGet httpGet = new HttpGet(url);
            httpGet = setHttpGetConfig(httpGet);
            // 设置请求头
            for (Map.Entry<String, String> param : headers.entrySet()) {
                httpGet.addHeader(param.getKey(), String.valueOf(param.getValue()));
            }
            response = httpClient.execute(httpGet);
            HttpEntity entity = response.getEntity();

            result = EntityUtils.toString(entity);
        } catch (Exception e) {
            throw e;
        } finally {
            // 关闭资源
            if (null != response) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != httpClient) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    /**
     * 发送多参数的get请求
     *
     * @param url   请求路径
     * @param param 参数Map
     * @return
     */

    public static Map<String, Object> doGetResultHeaders(String url, Map<String, String> param) {
        Map<String, Object> result = new HashMap<String, Object>(16);
        // 创建Httpclient对象
        CloseableHttpClient httpclient = HttpClients.createDefault();

        String resultString = "";
        CloseableHttpResponse response = null;
        try {
            // 创建uri
            URIBuilder builder = new URIBuilder(url);
            if (param != null) {
                for (String key : param.keySet()) {
                    builder.addParameter(key, param.get(key));
                }
            }
            URI uri = builder.build();
            // 创建http GET请求
            HttpGet httpGet = new HttpGet(uri);

            httpGet = setHttpGetConfig(httpGet);
            // 执行请求
            response = httpclient.execute(httpGet);
            // 判断返回状态是否为200
            if (response.getStatusLine().getStatusCode() == 200) {
                resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
                result.put("response", resultString);
                result.put("headers", response.getAllHeaders());
            }
        } catch (Exception e) {
            LOGGER.error("doGetResultHeaders url{},{}",url,e.getMessage());
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpclient.close();
            } catch (IOException e) {
                LOGGER.error("HttpClientUtil doGetResultHeaders error", e.getMessage());
            }
        }
        return result;
    }

    /**
     * 发送get请求
     *
     * @param url 请求路径
     * @return
     */
    public static String doGet(String url) {
        return doGet(url, null);
    }

    /**
     * 多个参数的post请求
     *
     * @param url   请求路径
     * @param param 参数map
     * @return
     */
    public static String doPost(String url, Map<String, String> param) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            // 创建参数列表
            if (param != null) {
                List<NameValuePair> paramList = new ArrayList<NameValuePair>();
                for (String key : param.keySet()) {
                    paramList.add(new BasicNameValuePair(key, param.get(key)));
                }
                // 模拟表单
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList, HTTP.UTF_8);
                httpPost.setEntity(entity);
            }
            httpPost = setHttpPostConfig(httpPost);
            // 执行http请求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            LOGGER.error("doPost url{},{}",url,e.getMessage());
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                LOGGER.error("HttpClientUtil doPost error", e.getMessage());
            }
        }
        return resultString;
    }

    /**
     * 发送post请求
     *
     * @param url 请求路径
     * @return
     */
    public static String doPost(String url) {
        return doPost(url, null);
    }

    /**
     * 多个参数的post请求
     * @param url   请求路径
     * @param param 参数map
     * @return
     */
    public static String doPost(String url, Map<String, String> param,Map<String, String> header) throws Exception{
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            if(header!=null) {
                header.forEach(httpPost::setHeader);
            }
            // 创建参数列表
            if (param != null) {
                List<NameValuePair> paramList = new ArrayList<NameValuePair>();
                for (String key : param.keySet()) {
                    paramList.add(new BasicNameValuePair(key, param.get(key)));
                }
                // 模拟表单
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
                httpPost.setEntity(entity);
            }
            // 执行http请求
            response = httpClient.execute(httpPost);
            if (response.getStatusLine().getStatusCode() == 200) {
                return EntityUtils.toString(response.getEntity(), "UTF-8");
            }else {
                LOGGER.warn("doRestfulHttp fail:{}:{}",response.getStatusLine().getStatusCode(),response.getStatusLine().getReasonPhrase());
                throw new Exception(response.getStatusLine().getReasonPhrase());
            }
        }finally {
            try {
                response.close();
            } catch (IOException e) {
                LOGGER.error("HttpClientUtil doPost error:{}", e.getMessage());
            }
        }
    }

    public static String doPostJson(String url, String json, Map<String, String> headers) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            // 把参数转换成json串
            httpPost.setEntity(new StringEntity(json, ContentType.APPLICATION_JSON));

            if (null != headers && headers.size() > 0) {
                Iterator<Map.Entry<String, String>> itMap = headers.entrySet().iterator();
                while (itMap.hasNext()) {
                    Map.Entry<String, String> entry = itMap.next();
                    httpPost.addHeader(entry.getKey(), entry.getValue());
                }
            }

            // 执行http请求
            response = httpClient.execute(httpPost);
            if (response.getStatusLine().getStatusCode() < 400) {
                return EntityUtils.toString(response.getEntity(), "UTF-8");
            }else {
                LOGGER.warn("doRestfulHttp fail:{}:{}",response.getStatusLine().getStatusCode(),response.getStatusLine().getReasonPhrase());
                throw new Exception();
            }
        } catch (Exception e) {
            LOGGER.error("HttpClientUtil doPostJson error url{},{}",url, e.getMessage());
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                LOGGER.error("HttpClientUtil doPostJson error{}", e.getMessage());
            }
        }

        return resultString;
    }

    /**
     * 发送参数为json字符串的post请求
     *
     * @param url  请求路径
     * @param json json字符串
     * @return
     */
    public static String doPostJson(String url, String json) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            // 创建请求内容
            StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
            httpPost.setEntity(entity);
            httpPost = setHttpPostConfig(httpPost);
            // 执行http请求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            LOGGER.error("doPostJson url{},{}",url,e.getMessage());
        } finally {
            try {
                if (response != null){
                    response.close();
                }
            } catch (IOException e) {
                LOGGER.error("HttpClientUtil doPostJson error", e.getMessage());
            }
        }

        return resultString;
    }

    /**
     * 发送参数为json字符串的post请求
     *
     * @param url  请求路径
     * @return
     */
    public static String doPostJson(String url) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            httpPost = setHttpPostConfig(httpPost);

            // 执行http请求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            LOGGER.error("doPostJson url{},{}",url,e.getMessage());
        } finally {
            try {
                if (response != null){
                    response.close();
                }
            } catch (IOException e) {
                LOGGER.error("HttpClientUtil doPostJson error", e.getMessage());
            }
        }

        return resultString;
    }

    /**
     * 发送参数为json字符串的put请求
     *
     * @param url  请求路径
     * @param json json字符串
     * @return
     */
    public static String doPutJson(String url, String json) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpPut httpPut = new HttpPut(url);
            // 创建请求内容
            StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
            httpPut.setEntity(entity);
            setHttpConfig(httpPut);
            // 执行http请求
            response = httpClient.execute(httpPut);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            LOGGER.error("doPutJson url{},{}",url,e.getMessage());
        } finally {
            try {
                if (response != null){
                    response.close();
                }
            } catch (IOException e) {
                LOGGER.error("HttpClientUtil doPutJson error", e.getMessage());
            }
        }

        return resultString;
    }

    /**
     * 发送参数为json字符串的put请求，带请求头
     *
     * @param url  请求路径
     * @param json json字符串
     * @return
     */
    public static String doPutJson(String url, String json, Map<String,String> headers) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpPut httpPut = new HttpPut(url);
            // 创建请求内容
            StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
            httpPut.setEntity(entity);
            setHttpConfig(httpPut);

            if (null != headers && headers.size() > 0) {
                Iterator<Map.Entry<String, String>> itMap = headers.entrySet().iterator();
                while (itMap.hasNext()) {
                    Map.Entry<String, String> entry = itMap.next();
                    httpPut.addHeader(entry.getKey(), entry.getValue());
                }
            }

            // 执行http请求
            response = httpClient.execute(httpPut);
            if (response.getStatusLine().getStatusCode() < 400) {
                return EntityUtils.toString(response.getEntity(), "UTF-8");
            }else {
                LOGGER.warn("doRestfulHttp fail:{}:{}",response.getStatusLine().getStatusCode(),response.getStatusLine().getReasonPhrase());
                throw new Exception(response.getStatusLine().getReasonPhrase());
            }
        } catch (Exception e) {
            LOGGER.error("doPutJson url{},{}",url,e.getMessage());
        } finally {
            try {
                if (response != null){
                    response.close();
                }
            } catch (IOException e) {
                LOGGER.error("HttpClientUtil doPutJson error", e.getMessage());
            }
        }

        return resultString;
    }

    /**
     * 发送delete请求
     *
     * @param url  请求路径
     * @return
     */
    public static String doDeleteJson(String url) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpDelete httpDelete = new HttpDelete(url);
            // 创建请求内容
            setHttpConfig(httpDelete);
            // 执行http请求
            response = httpClient.execute(httpDelete);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            LOGGER.error("doDeleteJson url{},{}",url,e.getMessage());
        } finally {
            try {
                if (response != null){
                    response.close();
                }
            } catch (IOException e) {
                LOGGER.error("HttpClientUtil doDeleteJson error", e.getMessage());
            }
        }

        return resultString;
    }

    /**
     * 发送delete请求，带请求头
     *
     * @param url  请求路径
     * @return
     */
    public static String doDeleteJson(String url,Map<String,String> headers) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpDelete httpDelete = new HttpDelete(url);
            // 创建请求内容
            setHttpConfig(httpDelete);

            if (null != headers && headers.size() > 0) {
                Iterator<Map.Entry<String, String>> itMap = headers.entrySet().iterator();
                while (itMap.hasNext()) {
                    Map.Entry<String, String> entry = itMap.next();
                    httpDelete.addHeader(entry.getKey(), entry.getValue());
                }
            }

            // 执行http请求
            response = httpClient.execute(httpDelete);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            LOGGER.error("doDeleteJson url{},{}",url,e.getMessage());
        } finally {
            try {
                if (response != null){
                    response.close();
                }
            } catch (IOException e) {
                LOGGER.error("HttpClientUtil doDeleteJson error", e.getMessage());
            }
        }

        return resultString;
    }

    /**
     * 发送多参数的get请求
     *
     * @param url 请求路径
     * @return
     */

    public static Map<String, Object> doGetForStream(String url) {
        Map<String, Object> result = new HashMap<String, Object>();
        InputStream in = null;
        CloseableHttpClient httpclient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        try {
            HttpGet httpGet = new HttpGet(url);
            // 执行请求
            response = httpclient.execute(httpGet);
            // 判断返回状态是否为200
            if (response.getStatusLine().getStatusCode() == 200) {
                in = response.getEntity().getContent();
            }
            result.put("inputstream", in);
            result.put("response", response);
            result.put("httpclient", httpclient);
        } catch (Exception e) {
            LOGGER.error(e.getMessage());
        }
        return result;
    }

    public static void freeResource(Map<String, Object> ioResource) {
        try {
            Object isObj = ioResource.get("inputstream");
            if (null != isObj) {
                InputStream is = (InputStream) isObj;
                is.close();
            }

            Object reponseObj = ioResource.get("response");
            if (null != reponseObj) {
                CloseableHttpResponse response = (CloseableHttpResponse) reponseObj;
                response.close();
            }

            Object clientObj = ioResource.get("httpclient");
            if (null != clientObj) {
                CloseableHttpClient client = (CloseableHttpClient) clientObj;
                client.close();
            }
        } catch (Exception e) {
            LOGGER.error("下载文件关闭资源异常", e);
        }
    }

    /**
     * 上传文件
     *
     * @param url      服务器地址
     * @param filePath 本地文件路径，全路径。
     * @return String
     */
    public static String postFile(String url, String filePath) {
        HttpClient httpClient = HttpClients.createDefault();
        String result = null;

        HttpPost httpPost = new HttpPost(url);

        httpPost = setHttpPostConfig(httpPost);

        File file = new File(filePath);
        FileBody bin = new FileBody(file);

        HttpEntity reqEntity = MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
                .addPart("file", bin).setCharset(CHARSET).build();
        httpPost.setEntity(reqEntity);
        HttpResponse httpResponse = null;
        try {
            //执行请求
            httpResponse = httpClient.execute(httpPost);
            int webStatus = httpResponse.getStatusLine().getStatusCode();

            if (200 == webStatus) {
                HttpEntity responseEntity = httpResponse.getEntity();
                if (null != responseEntity) {
                    result = EntityUtils.toString(responseEntity, CHARSET);
                }
                LOGGER.info("success to post file: [url={}, filePath={}, result={}]", url, filePath, result);

                EntityUtils.consume(responseEntity);
            } else {
                LOGGER.error("fail to post file:  [url={}, filePath={}, status={}]", url, filePath, webStatus);
            }
        } catch (IOException e) {
            LOGGER.error("exception to post file: [url={}, filePath={}]", url, filePath, e);
        }
        return result;
    }

    /**
     * 获取文件
     *
     * @param url 文件地址
     * @return InputStream
     */
    public static InputStream getFile(String url) {
        InputStream inputStream = null;

        HttpClient httpClient = HttpClients.createDefault();
        HttpResponse httpResponse = null;
        HttpGet httpGet = null;

        try {
            httpGet = new HttpGet(url);

            httpGet = setHttpGetConfig(httpGet);

            // 执行请求
            httpResponse = httpClient.execute(httpGet);

            int webStatus = httpResponse.getStatusLine().getStatusCode();

            if (200 == webStatus) {
                inputStream = httpResponse.getEntity().getContent();
            } else {
                LOGGER.error("fail to get file:  [url={}, status={}]", url, webStatus);
            }

        } catch (IOException e) {
            LOGGER.error("exception to get file:  [url={}]", url, e);
        }

        return inputStream;
    }

    /**
     * 获取文件
     * @param url 文件地址
     * @param header
     * @return InputStream
     */
    public static InputStream getFile(String url, Map<String, String> header) {
        InputStream inputStream = null;
        HttpClient httpClient = HttpClients.createDefault();
        HttpResponse httpResponse ;
        HttpGet httpGet;

        try {
            httpGet = new HttpGet(url);
            httpGet = setHttpGetConfig(httpGet);
            // 设置请求头
            if(!CollectionUtils.isEmpty(header)){
                header.forEach(httpGet::setHeader);
            }

            // 执行请求
            httpResponse = httpClient.execute(httpGet);
            int webStatus = httpResponse.getStatusLine().getStatusCode();
            if (200 == webStatus) {
                inputStream = httpResponse.getEntity().getContent();
            } else {
                LOGGER.error("fail to get file:  [url={}, status={}]", url, webStatus);
            }
        } catch (IOException e) {
            LOGGER.error("exception to get file:  [url={}]", url, e);
        }
        return inputStream;
    }

    /**
     * 校验链接是否有效
     * @param source
     * @return
     */
    public static boolean getRource(String source){
        try {
            URL url = new URL(source);
            URLConnection urlConnection = url.openConnection();
            urlConnection.setDoInput(true);
            urlConnection.setDoOutput(true);
            urlConnection.setUseCaches(false);
            urlConnection.setConnectTimeout(5000);
            urlConnection.setReadTimeout(5000);
            InputStream inputStream = urlConnection.getInputStream();
            if (source.equalsIgnoreCase(urlConnection.getURL().toString()))
            inputStream.close();
            return true;
        }catch (Exception e){
            return false;
        }
    }

    /**
     * 设置超时参数
     *
     * @param httpPost httpPost
     * @return HttpPost
     */
    private static HttpPost setHttpPostConfig(HttpPost httpPost) {
        RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT)
                .setSocketTimeout(SOCKET_TIMEOUT).setConnectTimeout(CONNECT_TIMEOUT).build();
        httpPost.setConfig(requestConfig);
        return httpPost;
    }

    /**
     * 设置超时参数
     *
     * @param httpGet httpGet
     * @return HttpGet
     */
    private static HttpGet setHttpGetConfig(HttpGet httpGet) {
        RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT)
                .setSocketTimeout(SOCKET_TIMEOUT).setConnectTimeout(CONNECT_TIMEOUT).build();
        httpGet.setConfig(requestConfig);
        return httpGet;
    }

    private static void setHttpConfig(HttpRequestBase http) {
        RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT)
                .setSocketTimeout(SOCKET_TIMEOUT).setConnectTimeout(CONNECT_TIMEOUT).build();
        http.setConfig(requestConfig);
    }


    /**
     * 从网络Url中下载文件
     * @param urlStr url地址
     * @param fileName 文件名称
     * @param savePath 保存地址
     * @param header 请求头
     * @return 文件保存路径
     * @author: songxulin
     * @date :  2021-01-19 9:14
     */
    public static String downLoadFromUrl(String urlStr, String fileName, String savePath, Map<String, String> header) throws IOException {

        URL url = new URL(urlStr);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        // 设置超时间为3秒
        conn.setConnectTimeout(3 * 1000);
        // 防止屏蔽程序抓取而返回403错误
        conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
        // 设置请求头
        if (!CollectionUtils.isEmpty(header)) {
            header.forEach(conn::setRequestProperty);
        }
        int responseCode = conn.getResponseCode();
        if (302 == responseCode || 307 == responseCode) {
            String redirectUrl = conn.getHeaderField("Location");
            if (redirectUrl != null && !redirectUrl.isEmpty()) {
                urlStr = redirectUrl;
                return downLoadFromUrl(urlStr, fileName, savePath, header);
            }
        }
        // 得到输入流
        try (InputStream inputStream = conn.getInputStream()) {

            // 获取自己数组
            byte[] getData = readInputStream(inputStream);

            // 文件保存位置
            File saveDir = new File(savePath);
            if (!saveDir.exists()) {
                saveDir.mkdirs();
            }
            File file = new File(saveDir + File.separator + fileName);
            try (FileOutputStream fos = new FileOutputStream(file)) {
                fos.write(getData);
            }
            return saveDir + File.separator + fileName;
        }
    }

    /**
     * 从输入流中获取字节数组
     *
     * @param inputStream
     * @return byte[]
     * @throws IOException
     */
    public static byte[] readInputStream(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[1024];
        int len = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while ((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        bos.close();
        return bos.toByteArray();
    }

}
